به نام خدا

SBU Logo

برنامه‌سازی پیشرفته

دانشگاه شهید بهشتی · دانشکده مهندسی کامپیوتر

دکتر مجتبی وحیدی اصل


آرایه های یک بعدی

نازنین زهرا فرهنج

فهرست مطالب

  1. معرفی آرایه ها
  2. مراحل تعریف آرایه ها
  3. متغیرهای اندیس
  4. مقداردهی اولیه آرایه ها
  5. پردازش آرایه ها (حل چند مثال)
  6. ارسال آرایه ها به متدها

انگیزه

این فصل را با یک سوال شروع می کنیم.

  • 10 عدد را از کاربر بگیرید، میانگین آنها را حساب کرده و بگویید چه تعدادی از آنها از میانگین بزرگتر هستند؟
  •  

    In [ ]:
    !pip install jbang
    import jbang
    jbang.exec("trust add https://github.com/jupyter-java")
    jbang.exec("install-kernel@jupyter-java")
    
    Failed to start the Kernel 'Java (JBang Python)'. 
    
    View Jupyter <a href='command:jupyter.viewOutput'>log</a> for further details. spawn EINVAL
    In [ ]:
    public class AnalyzeNumbers {
        public static void main(String[] args) {
            final int NUMBER_OF_ELEMENTS = 10;
            double[] numbers = new double[NUMBER_OF_ELEMENTS];
            double sum = 0;
    
            java.util.Scanner input = new java.util.Scanner(System.in);
            for (int i = 0; i < NUMBER_OF_ELEMENTS; i++) {
                System.out.print("Enter a new number: ");
                numbers[i] = input.nextDouble();
                sum += numbers[i];
            }
    
            double average = sum / NUMBER_OF_ELEMENTS;
    
            int count = 0; // The number of elements above average
            for (int i = 0; i < NUMBER_OF_ELEMENTS; i++)
                if (numbers[i] > average)
                    count++;
            
            System.out.println("Average is " + average);
            System.out.println("Number of elements above the average " + count);
        }
    }
    

    معرفی آرایه ها

    آرایه ساختمان داده ای است حاوی مجموعه ای از داده های هم نوع

    یک آرایه مثل مجموعه ای از متغیر ها است. که هر متغیر در آن یک عنصر (element) نامیده می شود.

    arrays

    مراحل تعریف آرایه ها

    • اعلان آرایه
      ;double[] nums
  • ایجاد آرایه
    ;nums = new double[4]
  • مقداردهی آرایه
    • مقداردهی آرایه همزمان با تعریف
      ;double[] nums = {1.9, 2.9, 3.4, 3.5}
  • مقداردهی آرایه پس از تعریف
    ;nums[0] = 1.9

    ;nums[1] = 2.9

    ;nums[2] = 3.4

    ;nums[3] = 3.5

  • arrays

    ایجاد آرایه ها

    ;arrayRefVar = new datatype[arraySize]

    myList = new double[10]

    اشاره به اولین عنصر آرایه myList[0]

    اشاره به آخرین عنصر آرایه myList[9]

    اعلان و ایجاد آرایه ها در یک گام

    ;datatype[] arrayRefVar = new datatype[arraySize]

    ;double[] myList = new double[10]

    ;datatype arrayRefVar[] = new datatype[arraySize]

    ;double myList[] = new double[10]

    هردو تعریف فوق صحیح است، ولی تعریف اول رایج تر و بهتر است.

    اندازه آرایه

    یک بار که آرایه ایجاد شود، اندازه آن ثابت می شود. این اندازه دیگر قابل تغییر نمی باشد. اندازه آرایه با دستور زیر محاسبه می شود:

    arrayRefVar.length

    برای مثال اعمال دستور بالا برروی آرایه myList که در اسلاید قبل با 10 عنصر تعریف شده است، مقدار 10 را برمی گرداند.

    myList.length //returns 10

    مقادیر پیش فرض

    هرگاه آرایه ای ایجاد شود، به عناصر آن مقداراولیه پیش فرض داده می شود:

    • صفر برای انواع داده اصلی عددی
    • 'u0000\' برای نوع کاراکتری
    • false برای نوع boolean

    متغیرهای اندیس

    • عناصر آرایه از طریق اندیس قابل دسترسی هستند.
  • اندیس های آرایه مبتنی بر 0 (0-based) هستند.
    • اولین خانه آنها دارای اندیس 0 و خانه آخر دارای اندیس arrayRefVar.length - 1 می باشد.
    • مثال نشان داده شده در شکل، آرایه myList را نشان می دهد که 10 مقدار نوع double و اندیس ها از 0 تا 9 هستند.
  • arrays
    • دسترسی به هر عنصر آرایه که به آن متغیر اندیس دار گفته می شود، با دستور زیر انجام می شود.
    ;arrayRefVar[index]

    استفاده از عناصر آرایه (متغیرهای اندیس دار)

    • پس از اینکه یک آرایه ایجاد شد، با یک متغیر اندیس دار (هریک از خانه‌های آرایه) مانند یک متغیر عادی رفتار می شود.
  • برای مثال، کد زیر مقدار دو عنصر آرایه (با اندیس 0) و (با اندیس 1) را جمع کرده و در عنصر دیگر (با اندیس 2) قرار می‌دهد.
  • ;myList[2] = myList[0] + myList[1]

    مقداردهی اولیه آرایه

    • اعلان، ایجاد و مقداردهی اولیه آرایه می تواند در یک گام انجام شود.
    ;double[] myList = {1.9, 2.9, 3.4, 3.5}
  • تمامی این اعمال در یک دستور انجام می شود.
  • دستور بالا معادل دستورات زیر است:
  • ;myList[0] = 1.9
    ;myList[1] = 2.9
    ;myList[2] = 3.4
    ;myList[3] = 3.5
  • استفاده از یک دستور برای مراحل اعلان، ایجاد و مقداردهی آرایه در بیشتر مواقع توصیه می شود.
  • توزیع این مراحل در چند دستور باید با دقت انجام شود. دستور زیر نادرست است:
  • ;double[] myList
    ;myList = {1.9, 2.9, 3.4, 3.5}

    برنامه حاوی آرایه

    در ادامه برنامه ای حاوی آرایه را به همراه ردگیری آن بررسی می کنیم.

     
    In [ ]:
    public class TestArray {
        public static void main(String[] args) {
            int[] values = new int[5];
            for(int i = 1; i < 5; i++) {
                values[i] = i + values[i - 1];
            }
            values[0] = values[1] + values[4];
        }
    }
    

    ردگیری برنامه حاوی آرایه

  • Declare array variable values, create an array, and assign its reference to values.
    arrays
  • i (=1) is less than 5
    values[1] = 1 + values[0] = 1 + 0 = 1
    iteration 1

    After i++, i becomes 2.

  • i (=2) is less than 5
    values[2] = 2 + values[1] = 2 + 1 = 3
    iteration 2

    After i++, i becomes 3.

  • i (=3) is less than 5
    values[3] = 3 + values[2] = 3 + 3 = 6
    iteration 3

    After i++, i becomes 4.

  • i (=4) is less than 5
    values[4] = 4 + values[3] = 4 + 6 = 10
    iteration 4

    After i++, i becomes 5.

  • i (=5) < 5 is false → Exit the loop.
    values[0] = values[1] + values[4] = 1 + 10 = 11
    final
  • پردازش آرایه ها

    در مثال های نشان داده شده در اسلایدهای بعدی، روش های مختلف پردازش آرایه ها بیان شده است.

     

    مقداردهی اولیه آرایه ها با مقادیر ورودی و چاپ آرایه ها

    In [ ]:
    public class ArrayInitializing {
        public static void main(String[] args) {
            double[] myList = new double[5];
            java.util.Scanner input = new java.util.Scanner(System.in);
            System.out.print("Enter " + myList.length + " values: ");
            for (int i = 0; i < myList.length; i++)
                myList[i] = input.nextDouble();
    
            for (int i = 0; i < myList.length; i++)
                System.out.print(myList[i] + " ");
        }
    }
    

    مقداردهی اولیه آرایه ها با مقادیر تصادفی و چاپ آرایه ها

     
    In [ ]:
    import java.util.Arrays;
    
    public class RandomArray {
        public static void main(String[] args) {
            double[] myList = new double[5];
            for (int i = 0; i < myList.length; i++)
                myList[i] = Math.random() * 100;
    
            System.out.println(Arrays.toString(myList));
        }
    }
    

    جمع کردن همه عناصر آرایه

     
    In [ ]:
    public class TotalArray {
        public static void main(String[] args) {
            double[] myList = new double[5];
            java.util.Scanner input = new java.util.Scanner(System.in);
            System.out.print("Enter " + myList.length + " values: ");
            for (int i = 0; i < myList.length; i++)
                myList[i] = input.nextDouble();
                
            double total = 0;
            for(int i = 0;i < myList.length; i++)
                total += myList[i];
            System.out.println(total);
        }
    }
    

    یافتن بزرگترین مقدار

     
    In [ ]:
    public class MaxArray {
        public static void main(String[] args) {
            double[] myList = new double[5];
            java.util.Scanner input = new java.util.Scanner(System.in);
            System.out.print("Enter " + myList.length + " values: ");
            for (int i = 0; i < myList.length; i++)
                myList[i] = input.nextDouble();
    
            double max = myList[0];
            for(int i = 1;i < myList.length; i++)
                if(myList[i] > max) max = myList[i];
            System.out.println(max);
        }
    }
    

    شافلینگ تصادفی

     
    In [ ]:
    public class ShuffleRandomArray {
        public static void main(String[] args) {
            double[] myList = new double[5];
            java.util.Scanner input = new java.util.Scanner(System.in);
            System.out.print("Enter " + myList.length + " values: ");
            for (int i = 0; i < myList.length; i++)
                myList[i] = input.nextDouble();
    
            for (int i = 0; i < myList.length; i++) {
            // Generate an index j randomly
                int index = (int)(Math.random()* myList.length);
                // Swap myList[i] with myList[j]
                double temp = myList[i];
                myList[i] = myList[index];
                myList[index] = temp;
            }
            for (int i = 0; i < myList.length; i++)
                System.out.print(myList[i] + " ");
        }
    }
    

    شیفت چرخشی عناصر-شیفت چپ

    فرض کنید خانه صفر آرایه، سمپ چپ لیست قرار گرفته است.

     
    In [ ]:
    public class ShiftArray {
        public static void main(String[] args) {
            double[] myList = new double[5];
            java.util.Scanner input = new java.util.Scanner(System.in);
            System.out.print("Enter " + myList.length + " values: ");
            for (int i = 0; i < myList.length; i++)
                myList[i] = input.nextDouble();
    
            double temp = myList[0]; // Retain the first element
            // Shift elements left
            for (int i = 1; i < myList.length; i++) {
                myList[i - 1] = myList[i];
            }
            // Move the first element to fill in the last position
            myList[myList.length - 1] = temp;
    
            for(int i = 0; i < myList.length; i++)
                System.out.print(myList[i] + " ");
        }
    }
    

    حلقه for توسعه یافته

    • JDK یک ساختار for معرفی کرده که به شما امکان می‌دهد، یک آرایه کامل را بدون استفاده از اندیس آرایه، خانه به خانه پیمایش کنید.
  • برای مثال، کد زیر تمامی عناصر در آرایه myList را نمایش می‌دهد:
  • for (double value : myList)
       ;System.out.println(value)
    • در حالت کلی قاعده نحوی به فرم زیر است:
    } for (elementType value : arrayRefVar)
    Process the value //
    {
    • اگر بخواهید عناصر را به ترتیب دیگری پیمایش کنید یا محتوای عناصر را به شکل دیگری تغییر دهید، باید از اندیس استفاده کنید!

    کپی آرایه ها

    • اغلب، در یک برنامه می خواهیم محتوای یک آرایه را در یک آرایه دیگر کپی کنیم.
  • در این مواقع ممکن است از = به صورت زیر استفاده کنید، که نتیجه ای خلاف انتظار شما خواهد داشت.
  • ;list2 = list1
    arrays

    کپی آرایه با استفاده از حلقه

     
    In [ ]:
    public class CopyArray {
        public static void main(String[] args) {
            int[] sourceArray = {2, 3, 1, 5, 10};
            int[] targetArray = new int[sourceArray.length];
            for (int i = 0; i < sourceArray.length; i++) {
                targetArray[i] = sourceArray[i];
                System.out.print(targetArray[i] + " ");
            }
        }
    }
    

    کپی آرایه با استفاده از عملیات arraycopy

    arraycopy(sourceArray, src_pos, targetArray, tar_pos, length);
     
    In [ ]:
    public class ArrayCopy {
        public static void main(String[] args) {
            int[] sourceArray = {2, 3, 1, 5, 10};
            int[] targetArray = new int[sourceArray.length];
            System.arraycopy(sourceArray, 0, targetArray, 0, sourceArray.length);
            for(int i = 0; i < targetArray.length; i++)
                System.out.print(targetArray[i] + " ");
        }
    }
    

    ارسال آرایه ها به متدها

     
    In [ ]:
    public class ParameterPassing {
        public static void main(String[] args) {
            int[] list = {3, 1, 2, 6, 4, 2};
            // Invoke the method
            printArray(list);
            printArray(new int[]{3, 1, 2, 6, 4, 2}); //Anonymous array
        }
        public static void printArray(int[] array) {
            for (int i = 0; i < array.length; i++) {
                System.out.print(array[i] + " ");
            }
            System.out.println();
        }
    }
    

    آرایه بی نام (Anonymous)

    • دستور
    • ;printArray(new int[]{3, 1, 2, 6, 4, 2})
  • با قاعده نحوی زیر یک آرایه ایجاد می کند:

    ;new dataType[]{literal0, literal1, ..., literalk}
  • در اینجا یک متغیر ارجاعی دارای نام برای آرایه وجود ندارد. به چنین آرایه ای، آرایه بی نام گفته می شود.
  • ارسال با مقدار

    • جاوا از سازوکار ارسال با مقدار برای ارسال پارامترها به یک متد استفاده می کند. تفاوت های مهمی بین ارسال مقدار متغیرهای انواع اصلی و ارسال آرایه ها وجود دارد.
  • برای پارامتری از نوع اولیه، مقداری که ارسال می شود تنها در داخل متد ممکن است تغییر داده شود، اما تاثیری بر متغیری که مقدار آن به متد ارسال شده است، ندارد.
  • برای پارامتری از نوع آرایه، مقدار پارامتر ارسال شده، ارجاعی به یک آرایه است (یک کپی از ریموت کنترلی که به آرایه اشاره می کند، به متد ارسال می شود). بنابراین هر تغییری برروی آرایه در داخل متد، بر آرایه اصلی که به متد ارسال شده، تاثیر خواهدگذاشت.
  • در ادامه مثالی ساده از این بخش می بینیم.

    In [ ]:
    public class Test {
        public static void main(String[] args) {
            int x = 1; // x represents an int value
            int[] y = new int[10]; //y represents an array of int values
            m(x, y); // Invoke m with arguments x and y
            System.out.println("x is " + x);
            System.out.println("y[0] is " + y[0]);
        }
        public static void m(int number, int[] numbers) {
            number = 1001; // Assign a new value to number
            numbers[0] = 5555; // Assign a new value to numbers[0]
        }
    }
    

    پشته فراخوانی مثال قبل

    درهنگام فراخوانی m(x, y)، مقادیر x , y به ترتیب به number و numbers ارسال می شوند. چون y حاوی مقدار ارجاعی به آرایه است، numbers به همان آرایه ای ارجاع می کند که y به آن ارجاع دارد.

    arrays
    arrays
    arrays

    جابجایی دو عنصر آرایه

    در ادامه جابجایی دو عنصر آرایه با دو روش primitive swap و reference swap را بررسی می کنیم.

    arrays
    In [ ]:
    public class SwapArray {
    
        public static void main(String[] args) {
            int[] a = {1, 2};
    
            // Primitive swap
            int n1 = a[0];
            int n2 = a[1];
            swap(n1, n2);
            System.out.println("After swap(int n1, int n2): " + a[0] + ", " + a[1]);
            // Output: 1, 2 → unchanged
    
            // Reference swap
            swapFirstTwoInArray(a);
            System.out.println("After swapFirstTwoInArray(a): " + a[0] + ", " + a[1]);
            // Output: 2, 1 → array is modified
        }
    
        public static void swap(int n1, int n2) {
            int temp = n1;
            n1 = n2;
            n2 = temp;
        }
    
        public static void swapFirstTwoInArray(int[] array) {
            int temp = array[0];
            array[0] = array[1];
            array[1] = temp;
        }
    }
    

    متد معکوس آرایه

    در ادامه کدی حاوی متد معکوس آرایه را به همراه ردگیری آن بررسی می کنیم.

     
    In [ ]:
    public class ReverseArray {
        public static void main(String[] args) {
            int[] list1 = {1, 2, 3, 4, 5, 6};
            int[] list2 = reverse(list1);
            for(int i = 0; i < list2.length; i++)
                System.out.print(list2[i] + " ");
        }
        public static int[] reverse(int[] list) {
            int[] result = new int[list.length];
            for (int i = 0, j = result.length - 1;
                 i < list.length; i++, j--) {
                result[j] = list[i];
            }
            return result;
        }
    }
    

    ردگیری متد معکوس آرایه

  • Declare result and create array.
    arrays
  • i (=0) is less than 6 and j = 5
    result[5] = list[0] = 1
    iteration 1

    After i++ and j--, i becomes 1 and j becomes 4.

  • i (=1) is less than 6 and j = 4
    result[4] = list[1] = 2
    iteration 2

    After i++ and j--, i becomes 2 and j becomes 3.

  • i (=2) is less than 6 and j = 3
    result[3] = list[2] = 3
    iteration 3

    After i++ and j--, i becomes 3 and j becomes 2.

  • i (=3) is less than 6 and j = 2
    result[2] = list[3] = 4
    iteration 4

    After i++ and j--, i becomes 4 and j becomes 1.

  • i (=4) is less than 6 and j = 1
    result[1] = list[4] = 5
    iteration 4

    After i++ and j--, i becomes 5 and j becomes 0.

  • i (=5) is less than 6 and j = 0
    result[0] = list[5] = 6
    iteration 4

    After i++ and j--, i becomes 6 and j becomes -1.

  • i (=6) < 6 is false → Exit the loop.
    Return result
    final
  • مسئله: شمارش تعداد مشاهدات یک حرف

    تعداد مشاهده هر حرف در آرایه دلخواه را شمارش کنید.

    In [ ]:
    public class CountLettersInArray {
        /**
         Main method
         */
        public static void main(String args[]) {
            // Declare and create an array
            char[] chars = {'t', 'h', 'i', 's', 'i', 's', 'n', 'e', 'w', 's', 'a', 'm', 'p', 'l', 'e', 'o', 'f', 'j', 'a', 'v', 'a'};
            // Display the array
            System.out.println("The lowercase letters are:");
            displayArray(chars);
            // Count the occurrences of each letter
            int[] counts = countLetters(chars);
            // Display counts
            System.out.println();
            System.out.println("The occurrences of each letter are:");
            displayCounts(counts);
        }
        /**
         * Display the array of characters
         */
        public static void displayArray(char[] chars) {
            // Display the characters in the array 20 on each line
            for (int i = 0; i < chars.length; i++) {
                if ((i + 1) % 20 == 0)
                    System.out.println(chars[i]);
                else
                    System.out.print(chars[i] + " ");
            }
        }
        /**
         * Count the occurrences of each letter
         */
        public static int[] countLetters(char[] chars) {
            // Declare and create an array of 26 int
            int[] counts = new int[26];
            // For each lowercase letter in the array, count it
            for (int i = 0; i < chars.length; i++)
                counts[chars[i] - 'a']++;
            return counts;
        }
        /**
         * Display counts
         */
        public static void displayCounts(int[] counts) {
            for (int i = 0; i < counts.length; i++) {
                if ((i + 1) % 10 == 0)
                    System.out.println(counts[i] + " " + (char) (i + 'a'));
                else
                    System.out.print(counts[i] + " " + (char) (i + 'a') + " ");
            }
        }
    }
    

    خودمون رو بسنجیم

    این بخش برای این طراحی شده که در پایان مطالعه این اسلاید، بتونی خودت رو محک بزنی و ببینی آیا مفاهیم رو به خوبی یاد گرفتی یا نه. سوالات زیر رو مرور کن و سعی کن بدون نگاه کردن به متن درس، به اون ها پاسخ بدی.

    • متدی بنویسید که عناصر یک آرایه از نوع عدد صحیح را مرتب کند.
    • برنامه ای بنویسید که در آرایه دلخواه (مثلا دارای 6 عنصر)، عنصر جدیدی را (مثلا عدد 35) در اندیس 2 آرایه اضافه کند و آرایه جدید را چاپ کند.
    • متدی بنویسید که عناصر تکراری یک آرایه را پیدا و چاپ کند.
    • متدی بنویسید که عناصر مشترک دو آرایه را پیدا و چاپ کند.

    پایان

    در صورت هرگونه سوال یا پیشنهاد میتونید با من در ارتباط باشید :)

    gmail: nanafarhanj@gmail.com

    telegram: @nana_f83